#include "app_dinogame.h"
#include "smarttimer.h"
#include "app_key.h"
#include "elog.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

uint8_t key_num = 0;
unsigned char cactus_category = 0;
unsigned char cactus_length = 8;
unsigned int score = 0;
unsigned int highest_score = 0;
int height = 0;
int cactus_pos = 128;
unsigned char cur_speed = 30;
char failed = 0;
char reset = 0;

const unsigned char DINO_JUMP[8][48] =
{
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
    0xe0, 0x80, 0x00, 0x00, 0x00, 0x80, 0xc0, 0xc0, \
    0xfe, 0xff, 0xfd, 0xbf, 0xaf, 0x2f, 0x2f, 0xe,  \
    0x03, 0x07, 0x0f, 0x1f, 0xff, 0xbf, 0x1f, 0x3f, \
    0xff, 0x8f, 0x07, 0x00, 0x01, 0x00, 0x00, 0x00, \
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
    0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, \
    0xf0, 0xc0, 0x80, 0x80, 0x80, 0xc0, 0xe0, 0xe0, \
    0xff, 0xff, 0xfe, 0x5f, 0xd7, 0x17, 0x17, 0x07, \
    0x01, 0x03, 0x07, 0x0f, 0x7f, 0x5f, 0x0f, 0x1f, \
    0x7f, 0x47, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, \
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
    0x80, 0xc0, 0x40, 0xc0, 0xc0, 0xc0, 0xc0, 0x80, \
    0xf8, 0xe0, 0xc0, 0xc0, 0xc0, 0xe0, 0xf0, 0xf0, \
    0xff, 0xff, 0xff, 0x2f, 0x6b, 0x0b, 0x0b, 0x03, \
    0x00, 0x01, 0x03, 0x07, 0x3f, 0x2f, 0x07, 0x0f, \
    0x3f, 0x23, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, \
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
    0xc0, 0xe0, 0xa0, 0xe0, 0xe0, 0xe0, 0xe0, 0xc0, \
    0x7c, 0xf0, 0xe0, 0xe0, 0xe0, 0xf0, 0xf8, 0xf8, \
    0xff, 0xff, 0xff, 0x17, 0x35, 0x05, 0x05, 0x01, \
    0x00, 0x00, 0x01, 0x03, 0x1f, 0x17, 0x03, 0x07, \
    0x1f, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
    0xe0, 0xf0, 0xd0, 0xf0, 0xf0, 0xf0, 0xf0, 0xe0, \
    0x3e, 0x78, 0xf0, 0xf0, 0xf0, 0xf8, 0xfc, 0xfc, \
    0xff, 0xff, 0x7f, 0x0b, 0x1a, 0x02, 0x02, 0x00, \
    0x00, 0x00, 0x00, 0x01, 0x0f, 0x0b, 0x01, 0x03, \
    0x0f, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
    0xf0, 0xf8, 0xe8, 0xf8, 0x78, 0x78, 0x78, 0x70, \
    0x1f, 0x3c, 0x78, 0xf8, 0xf8, 0xfc, 0xfe, 0xfe, \
    0xff, 0x7f, 0x3f, 0x05, 0x0d, 0x01, 0x01, 0x00, \
    0x00, 0x00, 0x00, 0x00, 0x07, 0x05, 0x00, 0x01, \
    0x07, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
    0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
    0xf8, 0xfc, 0xf4, 0xfc, 0xbc, 0xbc, 0xbc, 0x38, \
    0x0f, 0x1e, 0x3c, 0x7c, 0xfc, 0xfe, 0x7f, 0xff, \
    0xff, 0x3f, 0x1f, 0x02, 0x06, 0x00, 0x00, 0x00, \
    0x00, 0x00, 0x00, 0x00, 0x03, 0x02, 0x00, 0x00, \
    0x03, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
    0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, \
    0xfc, 0xfe, 0xfa, 0x7e, 0x5e, 0x5e, 0x5e, 0x1c, \
    0x07, 0x0f, 0x1e, 0x3e, 0xfe, 0x7f, 0x3f, 0x7f, \
    0xff, 0x1f, 0x0f, 0x01, 0x03, 0x00, 0x00, 0x00, \
    0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, \
    0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};

const unsigned char CLOUD[] =
{
    0x80, 0xc0, 0xe0, 0x70, 0xb0, 0xb0, 0xb0, 0x98, \
    0x88, 0x8e, 0x83, 0x83, 0x83, 0x81, 0x81, 0x93, \
    0x8e, 0x8c, 0x88, 0x88, 0x98, 0xb0, 0xf0, 0xc0
};

const unsigned char GROUND[] =
{
    0xc8, 0xc8, 0xc8, 0x28, 0x28, 0x28, 0x08, 0xc8, \
    0xc8, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, \
    0x8, 0x8, 0x8, 0x8, 0x8, 0x48, 0x8, 0x8, \
    0xc8, 0xc8, 0xc8, 0x8, 0x38, 0x38, 0x8, 0x8, \
    0x8, 0x8, 0x8, 0x48, 0x48, 0x8, 0x8, 0x8, \
    0x8, 0x8, 0x8, 0x28, 0x8, 0x48, 0x48, 0x48, \
    0x8, 0x8, 0x8, 0x28, 0x28, 0x8, 0x8, 0x8, \
    0x8, 0x8, 0x8, 0x8, 0x8, 0xc8, 0x8, 0x8, \
    0x8, 0x8, 0x8, 0x8, 0x8, 0x48, 0x8, 0x8, \
    0x8, 0x8, 0x8, 0x8, 0x38, 0x38, 0x8, 0x8, \
    0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, \
    0x8, 0x48, 0x8, 0x28, 0x28, 0x8, 0x48, 0x48, \
    0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, \
    0x8, 0x8, 0x8, 0x8, 0x28, 0x8, 0x8, 0x8, \
    0x8, 0x38, 0x38, 0x8, 0x68, 0x8, 0x8, 0x8, \
    0x8, 0x8, 0x8, 0x28, 0x8, 0x8, 0x8, 0x8, \
    0x8, 0x8, 0x8, 0x48, 0x8, 0x48, 0x48, 0x8, \
    0x8, 0x8, 0x8, 0x8, 0x8, 0x48, 0x48, 0x8, \
    0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x68, 0x8, \
    0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, \
    0x8, 0x28, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, \
    0xc8, 0xc8, 0x8, 0x9, 0x8, 0x8, 0x8, 0x8, \
    0x8, 0x38, 0x38, 0x8, 0x8, 0x28, 0x8, 0x9, \
    0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x28, \
    0x28, 0x8, 0x8, 0x8, 0x9, 0x8, 0x8, 0x8, \
    0x8, 0x8, 0x8, 0x8, 0x8, 0x68, 0x68, 0x8, \
    0xc9, 0xc8, 0xc8, 0x8, 0x8, 0x8, 0xc8, 0x8, \
    0x8, 0x8, 0x8, 0x28, 0x29, 0x8, 0x8, 0x8, \
    0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, \
    0x48, 0x49, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, \
    0x8, 0x8, 0x8, 0x8, 0x8, 0x68, 0x68, 0x8, \
    0x8, 0x28, 0x28, 0x8, 0x8, 0x8, 0x8, 0x8, \
    0x8, 0x8, 0x68, 0x68, 0x8, 0x8, 0xc8, 0xc8, \
    0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, \
    0x28, 0x28, 0x8, 0x28, 0x8, 0x8, 0x8, 0x8, \
    0x8, 0x28, 0x28, 0x28, 0x8, 0x8, 0x48, 0x8, \
    0x38, 0x38, 0x8, 0x8, 0x8, 0x8, 0xc8, 0x8, \
    0x8, 0x8, 0x8, 0x8, 0xc8, 0xc8, 0xc8, 0x28, \
    0x28, 0x28, 0x8, 0xc8, 0xc8, 0x8, 0x8, 0x8, \
    0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, \
    0x48, 0x48, 0x8, 0x8, 0xc8, 0xc8, 0xc8, 0x8, \
    0x38, 0x38, 0x8, 0x8, 0x8, 0x8, 0x8, 0x48, \
    0x48, 0x8, 0x8, 0x8, 0x8, 0x8, 0x28, 0x28, \
    0x8, 0x48, 0x48, 0x48, 0x8, 0x8, 0x8, 0x28, \
    0x28, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, \
    0x8, 0xc8, 0x8, 0x8, 0x8, 0xc, 0x6, 0x2, \
    0x42, 0x42, 0x6, 0xc, 0x8, 0x8, 0x8, 0x8, \
    0x38, 0x38, 0x8, 0x18, 0x18, 0x10, 0x10, 0x10, \
    0x10, 0x10, 0x18, 0x18, 0x8, 0x48, 0x8, 0x28, \
    0x28, 0x8, 0x48, 0x48, 0x8, 0x8, 0x8, 0x8, \
    0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x28, \
    0x28, 0x8, 0x8, 0x8, 0x8, 0x38, 0x38, 0x68, \
    0x68, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x28, \
    0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x48, \
    0x8, 0x48, 0x48, 0x8, 0x8, 0x8, 0x8, 0x8, \
    0x8, 0x48, 0x48, 0x8, 0x8, 0x8, 0x8, 0x8, \
    0x8, 0x68, 0x68, 0x8, 0x8, 0x8, 0x8, 0x8, \
    0x8, 0x8, 0x8, 0x8, 0x28, 0x28, 0x8, 0x8, \
    0x8, 0x8, 0x8, 0xc8, 0xc8, 0xc8, 0x8, 0x8, \
    0x8, 0x8, 0x8, 0x8, 0x28, 0x38, 0x38, 0x8, \
    0x8, 0x28, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, \
    0x8, 0x8, 0x28, 0x28, 0x28, 0x8, 0x8, 0x8, \
    0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, \
    0x8, 0x68, 0x68, 0x8, 0xc8, 0xc8, 0xc8, 0x8, \
    0x8, 0x8, 0xc8, 0x8, 0x8, 0x8, 0x8, 0x28, \
    0x28, 0x8, 0x8, 0x8, 0x8, 0xc, 0x4, 0x6, \
    0x2, 0x2, 0x6, 0xc, 0x4c, 0x48, 0x8, 0x8, \
    0x8, 0xc, 0x4, 0x6, 0x2, 0x2, 0x6, 0xc, \
    0xc, 0x68, 0x68, 0x8, 0x28, 0x28, 0x28, 0x8, \
    0x8, 0x8, 0x8, 0x8, 0x8, 0x68, 0x68, 0x68, \
    0x8, 0x8, 0xc8, 0xc8, 0x8, 0x8, 0x8, 0x8, \
    0x8, 0x8, 0x8, 0x8, 0x28, 0x28, 0x28, 0x28, \
    0x8, 0x8, 0x8, 0x8, 0x8, 0x28, 0x28, 0x28, \
    0x8, 0x8, 0x48, 0x28, 0x38, 0x38, 0x8, 0x8, \
    0x8, 0x8, 0xc8, 0x8, 0x8,
};

const unsigned char DINO[2][32] =
{
    0xe0, 0x80, 0x0, 0x0, 0x0, 0x80, 0xc0, 0xe0, \
    0xfe, 0xff, 0xfd, 0xbf, 0xaf, 0x2f, 0x2f, 0xe, \
    0x3, 0x7, 0xf, 0x1e, 0xff, 0xbf, 0x1f, 0x1f, \
    0x3f, 0x2f, 0x7, 0x0, 0x1, 0x0, 0x0, 0x0, \
    0xe0, 0x80, 0x0, 0x0, 0x0, 0x80, 0xc0, 0xe0, \
    0xfe, 0xff, 0xfd, 0xbf, 0xaf, 0x2f, 0x2f, 0xe, \
    0x3, 0x7, 0xf, 0x1e, 0x3f, 0x7f, 0x5f, 0x3f, \
    0xff, 0x8f, 0x7, 0x0, 0x1, 0x0, 0x0, 0x0
};

const unsigned char CACTUS_1[] = {
    0xf0, 0xf0, 0x0, 0xff, 0xff, 0x0, 0xf0, 0xf0, \
    0x3, 0x7, 0x86, 0xff, 0xff, 0x6, 0x3, 0x1
};

const unsigned char CACTUS_2[] = {
    0xf0, 0xe0, 0x0, 0xff, 0xfe, 0x80, 0xfc, 0x0, \
    0x0, 0x7c, 0xc0, 0xfe, 0xff, 0x0, 0x80, 0xfc, \
    0x3, 0x7, 0x6, 0xff, 0xff, 0x1, 0x10, 0x90, \
    0x90, 0x90, 0x0, 0xff, 0xff, 0x3, 0x3, 0x1
};

const unsigned char CACTUS_3[] = {
    0xf0, 0xe0, 0x0, 0xff, 0xfe, 0x80, 0xfc, 0x0, \
    0xfc, 0xfe, 0x0, 0xff, 0xff, 0x0, 0xf8, 0xf0, \
    0x0, 0xfe, 0x80, 0xfe, 0xff, 0xfe, 0x78, 0xfc, \
    0x13, 0x17, 0x6, 0xff, 0xff, 0x1, 0x10, 0x10, \
    0x13, 0x37, 0x4, 0xff, 0xff, 0x8, 0xf, 0x17, \
    0x10, 0x10, 0x1, 0xff, 0xff, 0x3, 0x13, 0x11
};

const unsigned char CACTUS_4[] = {
    0xf0, 0xe0, 0x0, 0xff, 0xfe, 0x0, 0xf0, 0x0, 0xc0, 0x0, 0xff, 0xfe, 0x60, 0x3c, 0x80, 0x0,
    0x0, 0x7c, 0xc0, 0xfe, 0xff, 0x0, 0xf0, 0xf8, 0x43, 0x47, 0x86, 0xff, 0xff, 0x26, 0xa3,
    0xa0, 0x27, 0x4, 0xff, 0xff, 0x0, 0x8, 0xff, 0x88, 0x2f, 0x0, 0x0, 0xff, 0xff, 0x6, 0x23, 0x21
};

const unsigned char RESTART[] =
{
    0xfc, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x3f, \
    0x3f, 0x3f, 0xf, 0x1f, 0x3f, 0xff, 0xff, 0xff, \
    0x3f, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, \
    0xff, 0xff, 0xff, 0xff, 0xff, 0x0, 0x0, 0x7e, \
    0x7e, 0x7e, 0x78, 0x7c, 0x7e, 0x7f, 0x7f, 0x7f, \
    0x7e, 0x0, 0x0, 0xff, 0xff, 0xff, 0xff, 0xff, \
    0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0xfc, \
    0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, \
    0xfc, 0xfc, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f,
};

static void oled_drawbmp_block_clear(int bx, int by, int clear_size)
{
    unsigned int i;
    oled1306_set_cursor(by, bx);
    for(i = 0; i < clear_size; i++)
    {
        if((bx + i) > 128)
            break;
        ssd1306_write_data(0x00);
    }
}

/*
*draw cloud
*/
void oled1306_draw_cloud(void)
{
    static int pos = 64;
    static char height = 0;
    char speed = 3;
    int x;
    int start_x = 0;
    int length = sizeof(CLOUD);
    unsigned char byte;

    log_d("length == %d\r\n", length);

    if((pos + length) <= -speed)
    {
        pos = 128;
        height = rand() % 3;
        log_e("why\r\n");
    }
    if(pos < 0)
    {
        start_x = -pos;
        oled1306_set_cursor((1 + height), 0);
    }
    else
    {
        oled1306_set_cursor((1 + height), pos);
    }
    for(x = start_x; x < (length + speed); x++)
    {
        if(pos + x > 127)
        {
            log_e("pos over range\r\n");
            break;
        }
        if(x < length)
            byte = CLOUD[x];
        else
            byte = 0x00;
        ssd1306_write_data(byte);
    }
    pos = pos - speed;
}

void oled1306_draw_ground(void)
{
    static unsigned int pos = 0;
    unsigned char speed = 5;
    unsigned int ground_length = sizeof(GROUND);
    unsigned char x;

    oled1306_set_cursor(7, 0);
    for(x = 0; x < 128; x++)
    {
        ssd1306_write_data(GROUND[(x + pos) % ground_length]);
    }

    pos = pos + speed;
}

/*
*draw jumping dino
*/
int oled1306_draw_dino_jump(char reset)
{
    char speed_arr[] = {1, 1, 3, 3, 4, 4, 5, 6, 7};
    static int speed_idx = sizeof(speed_arr) - 1;
    static int height = 0;
    static char dir = 0;
    unsigned int j = 0;
    unsigned char x, y;
    char offset = 0;
    unsigned char byte;

    if(reset == 1)
    {
        height = 0;
        dir = 0;
        speed_idx = sizeof(speed_arr)-1;
        return 0;
    }
    if(dir == 0)
    {
        height += speed_arr[speed_idx];
        speed_idx --;
        if(speed_idx < 0)
            speed_idx = 0;
    }
    if(dir == 1)
    {
        height -= speed_arr[speed_idx];
        speed_idx ++;
        if (speed_idx > sizeof(speed_arr) - 1)
            speed_idx = sizeof(speed_arr) - 1;
    }
    if(height >= 31)
    {
        dir = 1;
        height = 31;
    }
    if(height <= 0)
    {
        dir = 0;
        height = 0;
    }
    if(height <= 7) 
        offset = 0;
    else if(height <= 15)
        offset = 1;
    else if(height <= 23)
        offset = 2;
    else if(height <= 31)
        offset = 3;
    else 
        offset = 4;
    for(y = 0; y < 3; y++)
    {
        oled1306_set_cursor(5 - offset + y, 16);
        for(x = 0; x < 16; x++)
        {
            j = (y * 16) + x;
            byte = DINO_JUMP[height % 8][j];
            ssd1306_write_data(byte);
        }
    }
    if(dir == 0)
        oled_drawbmp_block_clear(16, 8- offset, 16);
    if(dir == 1)
        oled_drawbmp_block_clear(16, 4- offset, 16);
    return height;
}

/*
*draw dinosaur
*/
void oled1306_draw_dino(void)
{
    static unsigned char dino_dir = 0;
    unsigned int j = 0;
    unsigned char x, y;
    unsigned char byte;

    dino_dir++;
    dino_dir = dino_dir % 2;
    for(y = 0; y < 2; y++)
    {
        oled1306_set_cursor(6 + y, 16);
        for(x = 0; x < 16; x++)
        {
            j = (y * 16) + x;
            byte = DINO[dino_dir][j];

            ssd1306_write_data(byte);
        }
    }
}

/*
*draw cactus obstacle
*/
void oled1306_draw_cactus_obstacle(void)
{
    char speed = 5;
    static int pos = 128;
    int start_x = 0;
    int length = sizeof(CACTUS_2)/2;

    unsigned int j=0;
    unsigned char x, y;
    unsigned char byte;

    if(pos + length <= 0)
    {
        oled_drawbmp_block_clear(0, 6, speed);
        pos = 128;
    }

    for(y = 0; y < 2; y++)
    {
        if(pos < 0)
        {
            start_x = -pos;
            oled1306_set_cursor(6 + y, 0);
        }
        else
        {
            oled1306_set_cursor(6 + y, pos);
        }

		for(x = start_x; x < length; x++)
		{
			if(pos + x > 127)
                break;
            j = (y * length) + x;
            byte = CACTUS_2[j];
            ssd1306_write_data(byte);
        }
    }
    oled_drawbmp_block_clear(pos + length, 6, speed);//清除残影
    pos = pos - speed;
}

/*
*draw random catus obstacle
*/
int oled1306_draw_cactus_random(unsigned char ver, unsigned char reset)
{
    char speed = 5;
    static int pos = 128;
    int start_x = 0;
    int length = 0;

    unsigned int j = 0;
    unsigned char x, y;
    unsigned char byte;
    if(reset == 1)
    {
        pos = 128;
        oled_drawbmp_block_clear(0, 6, speed);
        return 128;
    }
    if(ver == 0)
        length = 8;
    else if(ver == 1)
        length = 16;
    else if(ver == 2 || ver == 3)
        length = 24;

    for(y = 0; y < 2; y++)
    {
        if(pos < 0)
        {
            start_x = -pos;
            oled1306_set_cursor(6 + y, 0);
        }
        else
        {
            oled1306_set_cursor(6 + y, pos);
        }

        for(x = start_x; x < length; x++)
        {
            if (pos + x > 127)
                break;

            j = (y * length) + x;
            if(ver == 0)
                byte = CACTUS_1[j];
            else if(ver == 1)
                byte = CACTUS_2[j];
            else if(ver == 2)
                byte = CACTUS_3[j];
            else
                byte = CACTUS_4[j];
            ssd1306_write_data(byte);
        }
    }

    oled_drawbmp_block_clear(pos + length, 6, speed);

    pos = pos - speed;
    return pos + speed;
}

/*
*
*/
void oled1306_draw_restart(void)
{
    unsigned int j=0;
    unsigned char x, y;
    unsigned char byte;
    for(y = 2; y < 5; y++)
    {
        oled1306_set_cursor(y, 52);
        for(x = 0; x < 24; x++)
        {
            byte = RESTART[j++];
            ssd1306_write_data(byte);
        }
    }
    OLED_ShowString(10, 3, "GAME");
    OLED_ShowString(86, 3, "OVER");
}

void Game_control(void)
{
    #if 1
    while(1)
    {
        if(failed == 1)
        {
            oled1306_draw_restart();

            key_num = read_gpio_state();
            if(key_num == 2)
            {
                if(score > highest_score)
                {
                    highest_score = score;
                }
                score = 0;
                failed = 0;
                height = 0;
                reset = 1;
                oled1306_draw_dino_jump(reset);
                oled1306_draw_cactus_random(cactus_category, reset);
                OLED_Fill_All(0x00);
                log_d("start game\r\n");
            }
            continue;
        }

        score ++;
        if(height <= 0)
            key_num = read_gpio_state();

        oled1306_draw_ground();
        oled1306_draw_cloud();

        if(height > 0 || key_num == 1)
            height = oled1306_draw_dino_jump(reset);
        else
            oled1306_draw_dino();

        cactus_pos = oled1306_draw_cactus_random(cactus_category, reset);
        if(cactus_category == 0)
            cactus_length = 8;
        else if(cactus_category == 1)
            cactus_length = 16;
        else
            cactus_length = 24;

        if(cactus_pos + cactus_length < 0)
        {
            cactus_category = rand() % 4;
            oled1306_draw_cactus_random(cactus_category, 1);
        }

        if((height < 16) && ((cactus_pos>=16 && cactus_pos <= 32) || \
                                ((cactus_pos + cactus_length) >= 16 && \
                                    (cactus_pos + cactus_length) <= 32)))
        {
            failed = 1;
        }
        OLED_ShowString(1, 1, "HI:");
        oled1306_show_num(2, 0, highest_score, 5);
        oled1306_show_num(2, 1, score, 5);

        reset = 0;

        cur_speed = (score / 20);
        if(cur_speed > 29)
            cur_speed = 29;
        stim_delay(30 - cur_speed);
        key_num = 0;
    }
    #endif
}
